package cn.com.zcode.exam.service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.com.zcode.core.service.BaseServiceSupport;
import cn.com.zcode.dic.jstl.DictionaryUtil;
import cn.com.zcode.exam.dao.ExamDao;
import cn.com.zcode.exam.model.Answer;
import cn.com.zcode.exam.model.Examination;
import cn.com.zcode.exam.model.PQConnector;
import cn.com.zcode.exam.model.Paper;
import cn.com.zcode.exam.model.Question;
import cn.com.zcode.exam.model.StaticInfo;
import cn.com.zcode.exam.model.Wrong;
import cn.com.zcode.user.model.User;

public class ExamServiceImpl extends BaseServiceSupport<ExamDao> implements ExamService {

	@Override
	public Question addQuestion(Question question) {
		if (question != null) {
			Paper paper = question.getPaper();
			if (paper != null) {
				if (paper.getId() == null) {
					paper.setMain(true);
					mainDao.save(paper);
				}

				mainDao.addQuestion(question);
				mainDao.save(new PQConnector(question.getId(), question.getPaper().getId()));
			}

		}
		return question;
	}

	@Override
	public Question updateQuestion(Question question) {
		if (question != null) {
			mainDao.saveOrUpdate(question);
		}
		return question;
	}

	@Override
	public List<Question> findQuestions(String pmp) {
		return mainDao.listQuestions(pmp);
	}

	@Override
	public Paper getPaper(String pid) {

		return mainDao.getPaperById(pid);
	}

	@Override
	public Paper addPaper(Paper paper) {
		return mainDao.save(paper);
	}

	@Override
	public Answer addAnswer(Answer answer) {
		return mainDao.save(answer);
	}

	@Override
	public Wrong addWrong(Wrong wrong) {
		return mainDao.save(wrong);

	}

	@Override
	public List<Paper> findPapers(String key, String userid) {
		return mainDao.listPapersInfo(key, userid);
	}

	@Override
	public Wrong getWrong(String userId, String questionId) {

		return mainDao.getWrong(userId, questionId);
	}

	@Override
	public List<Question> findWrongQuestions(String type, String userId) {
		List<Question> list = mainDao.findMyWrongQuestionsByType(type, userId);
		return list;
	}

	@Override
	public List<StaticInfo> getStatinfo(String string) {
		return mainDao.listStaticInfoByType(string);
	}

	@Override
	public Paper getPaper(String type, String title, int state, String userid) {

		return mainDao.getPaper(type, title, state, userid);
	}

	@Override
	public Paper mergePaper(Paper paper) {

		return mainDao.merge(paper);
	}

	@Override
	public List<StaticInfo> getPaperInfo(String type) {

		return mainDao.getPaperInfo(type);
	}

	@Override
	public List<Question> searchQuestions(String keyword, String userId) {

		return mainDao.searchQuestions(keyword, userId);
	}

	@Override
	public Question getQuestion(String id) {
		return mainDao.getQuestion(id);
	}

	@Override
	public List<Examination> findExamination(String key, String userid) {
		return mainDao.listExamination(key, userid);
	}

	@Override
	public List<Question> findNewExamQuestions(String pid) {

		return mainDao.listNewExamQuestions(pid);
	}

	@Override
	public List<Question> findLastExamQuestions(String eid) {

		return mainDao.listLastExamQuestions(eid);
	}

	@Override
	public Examination saveFinishExamination(String eid) {
		Examination exam = mainDao.get(eid, Examination.class);
		List<Question> list = mainDao.getDoneInfo(exam.getId(), exam.isForWrong());
		if (list != null) {
			int right = 0;
			int wrong = 0;
			for (Question question : list) {
				Answer answer = question.getAnswerInfo();
				if (answer != null && answer.isCorrect()) {
					right++;
				} else {
					wrong++;
				}
			}
			if (Examination.FINISH != exam.getState()) {
				double score = (double) right / (right + wrong);
				exam.setState(Examination.FINISH);
				exam.setEndTime(new Date());
				exam.setScore(score);
				mainDao.edit(exam);
			}
		}
		exam.setQuestions(list);
		return exam;
	}

	@Override
	public List<Paper> findPaperByUser(String string, User user) {
		return mainDao.findPaperByUser(string, user);
	}

	@Override
	public Examination getLastExamination(String paperId, String userId) {

		Examination examination = mainDao.getLastExamination(paperId, userId);
		this.getAnswerInfo(examination);
		return examination;

	}

	private void getAnswerInfo(Examination examination) {
		if (examination != null) {
			String eid = examination.getId();
			int questionCount = 0;
			if (examination.isForWrong()) {
				questionCount = mainDao.getWrongQuestionsCount(eid);

			} else {
				questionCount = mainDao.getQuestionsCount(eid);

			}
			examination.setQuestionCount(questionCount);
			List<Answer> answers = mainDao.findDoneAnswers(examination.getId());

			int correntCount = 0;
			int wrongCount = 0;
			if (answers != null && !answers.isEmpty()) {
				for (Answer answer : answers) {
					if (answer.isCorrect()) {
						correntCount++;
					} else {
						wrongCount++;
					}
				}
				Answer answer = answers.get(answers.size() - 1);
				Date date = answer.getAnswerDate();
				examination.setLastAnswerDate(date);
			} else {
				examination.setLastAnswerDate(examination.getStaTime());
			}
			examination.setCorrentCount(correntCount);
			examination.setWrongCount(wrongCount);
		}
	}

	@Override
	public List<Paper> findEditablePaper(String type, User user) {
		return mainDao.findEditablePaper(type, user.getId());

	}

	@Override
	public List<Question> findRemainingQuestions(String eid, boolean isForWrong, int length, String outstr) {

		List<Question> list = null;
		outstr = outstr != null ? outstr : "";
		String[] out = outstr.split(",");
		if (isForWrong) {
			list = mainDao.findRemainingWrongQuestions(eid, length, out);

		} else {
			list = mainDao.findRemainingQuestions(eid, length, out);

		}
		// if(list!=null){
		// Map<String,Question> map = new HashMap<String,Question>();
		// for (Question question : list) {
		// String id= question.getId();
		// map.put(id,question);
		// }
		// List<Question> accessorys =
		// mainDao.findAccessoriesByQids(map.keySet());
		// if(accessorys!=null){
		// for (Question question : accessorys) {
		// String id= question.getId();
		// map.put(id,question);
		// String priid = question.getPrimaryId();
		// Question parent = map.get(priid);
		// parent.getAccessorys().add(question);
		// }
		//
		// }
		// this.fillQuestionWithOptions( map);
		// }
		return list;
		// }
		// private void fillQuestionWothAttachment(){
		//
		// }
		// private void fillQuestionWithOptions(Map<String,Question> map){
		// List<Option> ops = mainDao.findOptionsByQids(map.keySet());
		// for (Option option : ops) {
		// String qid = option.getQuestionId();
		// Question quest = map.get(qid);
		// quest.addOption(option);
		// }
	}

	@Override
	public void saveWrongPaper(User user) {
		Paper paper = new Paper();
		paper.setId(Paper.PAPER_WRONG_INFO);
		paper.setCreater(user);
		paper.setState(Paper.STATE_WRONG);
		paper.setTitle("我的错题");
		paper.setMain(true);
		paper.setOrderIndex(9999);
		paper.setCreateDate(new Date());
		this.mainDao.saveWithId(paper);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cn.com.zcode.exam.service.ExamService#getStartExamination(cn.com.zcode
	 * .user.model.User, java.lang.String, boolean)
	 */
	@Override
	public Examination getStartExamination(User user, String paperId, boolean continueExam) {
		Examination examination = mainDao.getLastExamination(paperId, user.getId());
		if (examination != null && !continueExam) {
			examination.setState(Examination.INVIAL);
			examination.setScore(0);
			mainDao.edit(examination);
			examination = null;
		}
		if (examination == null) {
			Paper paper = this.getPaper(paperId);
			examination = new Examination();
			examination.setStaTime(new Date());
			examination.setTitle(paper.getTitle());
			examination.setPaper(paper);
			examination.setUser(user);
			examination.setForWrong(paper.getState() == Paper.STATE_WRONG);
			mainDao.save(examination);

		}
		this.getAnswerInfo(examination);
		return examination;
	}

}
